#! /usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import threading
import time
import datetime
import ftplib
from ftplib import FTP

import global_var
from db_ctrl  import * #add mongodb read/write
from plate_syndata import *
from plate_shape import *

#usage ftpmon= CFtpMoni()
#      ftpmon.start()
#      ftpmon.join()
log = global_var.gl_log

class CFtpMon(threading.Thread):
    db = CDBProcessor()
    db.connect()
    #synpd = CPlateDataSyn()
    shp = CShapeData(db)

    def __init__(self, threadID, name):
        
        threading.Thread.__init__(self)
        log.info("ftp thread start...")
        self.threadID = threadID
        self.name = name
        self.ftp = None
        self.conf = None
       
    #监控ftp下的文件变化
    def run(self):

        #print("date:", type(datetime), datetime)
        now = datetime.datetime.now()
        
        last_dir = "/{}/{:02d}".format(now.year,now.month)
        last_dir = self.getConfVal("last_dir", last_dir)

        last_files = self.getLastFiles()
        
        self.ftp_addr = self.getConfVal("ftp_addr","192.168.100.51")
        self.ftp_port = self.getConfVal("ftp_port",21)
        self.ftp_usr = self.getConfVal("ftp_usr","taoge")
        self.ftp_pwd = self.getConfVal("ftp_pwd","taoge")
        
        
        while global_var.gl_RUNNING:
            try:
                sleep_time = 1
                if self.ftp==None:
                    self.ftp = FTP()
                    #self.ftp.set_debuglevel(2)
                    self.ftp.connect(self.ftp_addr, self.ftp_port)
                    self.ftp.login(self.ftp_usr, self.ftp_pwd)
                    #log.info("ftp login {}:{}".format(ftp_addr,ftp_port))

                
                #str_year = "{}".format(now.year)
                #str_mon = "{:02d}".format(now.month)
                now = datetime.datetime.now()
                self.DIRN = "/{}/{:02d}".format(now.year,now.month)

                if last_files == None or len(last_files)==0:            
                    last_files = self.getConfVal("last_files",None)
                    
                if last_files:
                    if self.DIRN != last_dir:
                        last_dir = self.DIRN
                        self.setConfVal("last_dir", last_dir)
                        last_files = []
                self.ftp.cwd(self.DIRN)#cd [dir]
                #_ls = self.ftp.retrlines('LIST')
                try:
                    all_files = self.ftp.nlst()
                except ftplib.error_temp as e:
                    log.error("ftp nlst error，reconnect")
                    self.ftp.quit()
                    self.ftp.connect(self.ftp_addr, self.ftp_port)
                    self.ftp.login(self.ftp_usr, self.ftp_pwd)
                    self.ftp.cwd(self.DIRN)
                    all_files = self.ftp.nlst()

                #print(_ls)
                set_all_files=set(all_files)
                if last_files==None:
                    set_last_files = set_all_files
                else:   
                    set_last_files=set(last_files)
                
                add_files = list(set_all_files-set_last_files)
                add_files.sort()

                if len(add_files):
                    self.setConfVal("last_files",all_files)
                    last_files=all_files
                
                for _it in add_files:
                    str_pid = self.split_fn(_it)
                    log.info("new: ({}), ==> {}".format(str_pid, _it))
                    if str_pid==None or len(str_pid) < 10:
                        pass
                    else:
                        self.download(str_pid,_it)
                        #
                                    
                #for ftp download delay, unknown it useful
                if len(add_files):
                    sleep_time=5
                
                try:
                    self.ftp.quit()
                except Exception as e:
                    log.Error( "ftp quit error {}".format(e))

                self.ftp = None

            except ftplib.error_perm:  
                log.error('ERRORL cannot CD to "%s"' % self.DIRN)  
                log.error("error at: {}:{}".format(e.__traceback__.tb_frame.f_globals["__file__"],e.__traceback__.tb_lineno))
                self.ftp.quit()
                self.ftp = None
            except ftplib.error_temp as e:
                log.error("ftplib.error_temp {}".format(e))
                log.error("error at: {}:{}".format(e.__traceback__.tb_frame.f_globals["__file__"],e.__traceback__.tb_lineno))
                self.ftp.quit()
                self.ftp = None
                sleep_time=5
            except Exception as e:
                log.error("ftp Error: {}".format(e))
                log.error("error at: {}:{}".format(e.__traceback__.tb_frame.f_globals["__file__"],e.__traceback__.tb_lineno))
                
                self.ftp.close()
                self.ftp = None
            
            time.sleep(sleep_time)
    
    def download(self, plate_id, file_from, file_to=""):
        bufsize = 1024                #设置缓冲块大小
        if len(file_to)==0:
            file_to = file_from

        try:
            log.info("start download file: %s" % file_from)

            file_path=self.getConfVal("download_path","./download")
            file_name = "{}/{}".format(file_path,file_to)

            # fp = open(file_path+"/"+file_to,'wb')     #以写模式在本地打开文件
            # fp = open(file_name,'wb') 

            t1 = datetime.datetime.now()
            with open(file_name,'wb') as fp:
                self.ftp.retrbinary('RETR ' + file_from, fp.write) #接收服务器上文件并写入本地文件
                
            log.info("ftp retr time: {}".format((datetime.datetime.now()-t1).microseconds))
            #log.info("file {} size: {}".format(file_name, os.path.getsize(file_name)))
            #log.info("sleep 1s and read the data file")
            #time.sleep(5)
            self.shp.extract_data(file_name, plate_id)
        except ftplib.error_temp as e:
            log.error("ftplib.error_temp {}".format(e))
            log.error("error at: {}:{}".format(e.__traceback__.tb_frame.f_globals["__file__"],e.__traceback__.tb_lineno))
            
            self.ftp.quit()
            self.ftp.connect(self.ftp_addr, self.ftp_port)
            self.ftp.login(self.ftp_usr, self.ftp_pwd)
            self.ftp.cwd(self.DIRN)
            with open(file_name,'wb') as fp:
                self.ftp.retrbinary('RETR ' + file_from, fp.write) #接收服务器上文件并写入本地文件

        except Exception as e:
            log.error("ftp download err {}".format(e))
    
    #split file name to plate id
    def split_fn(self, file_name):
        """
        ex:
        2019-12-30 13.10.47 -112903862304        .sdf
        """
        try:
            lst_fn = file_name.split(" -")
            str_pid = lst_fn[-1].split(".")[0]
            str_pid = str_pid.strip()
            
            return str_pid
            
        except Exception as e:
            print("split_fn err", e)
            return None



    def close_conf(self):
        if self.conf:
            self.conf.close()
            self.conf=None

    def open_conf(self):
        if self.conf==None:
            self.conf = CDBConfig()

    def getConfVal(self, conf_name, default_val = None):
        self.open_conf()
        ret_val = self.conf.read(conf_name)
        if ret_val==None:
            ret_val = default_val
        self.close_conf()
        return ret_val
        

    def setConfVal(self, conf_name, conf_val):
        self.open_conf()
        self.conf.write(conf_name,conf_val)
        self.close_conf()
        

    def getLastFiles(self):
        
        self.open_conf()
        self.conf.read("last_files")
        last_files = self.conf.read("last_files")
        self.close_conf()
        return last_files
    
    def setLastFiles(self, last_files):
        self.open_conf()
        self.conf.write("last_files",last_files)
        self.close_conf()
        return True


if __name__=="__main__":
    ftp_mon = CFtpMon(1,"ftp mon")
    ftp_mon.start()
    ftp_mon.join()
